import 'package:flutter/material.dart';

/// 默认显示数据行,多出部分先隐藏
///
/// example:
///
/// ExpandableText(
///   "人生中有黑暗,也有光芒,而你,是其中的一束,所有光芒中耀眼的那一束.",
///   maxLines: 2,
///   style: textStyle,
///   markerStyle: markerStyle,
///   atName: "张三",
/// ),
class ExpandableText extends StatefulWidget {
  /// 显示文本
  final String text;

  /// 默认显示行数
  final int? maxLines;

  /// 文本颜色
  final TextStyle? style;

  /// 是否展开(默认收起)
  final bool expand;

  /// 副文本样式
  final TextStyle? markerStyle;

  /// 回复谁
  final String atName;

  const ExpandableText(
    this.text, {
    Key? key,
    this.maxLines,
    this.style,
    this.markerStyle,
    this.expand = false,
    this.atName = '',
  }) : super(key: key);

  @override
  createState() => _ExpandableTextState();
}

class _ExpandableTextState extends State<ExpandableText> {
  late bool expand;
  TextStyle? style;
  int? maxLines;

  @override
  void initState() {
    expand = widget.expand;
    style = widget.style;
    maxLines = widget.maxLines;
    super.initState();
  }

  Widget buildOrdinaryText() {
    final text = widget.text;
    return LayoutBuilder(builder: (_, size) {
      final tp = TextPainter(
        text: TextSpan(text: text, style: style),
        maxLines: maxLines,
        textDirection: TextDirection.ltr,
      );
      tp.layout(maxWidth: size.maxWidth);

      if (!tp.didExceedMaxLines) return Text(text, style: style);

      return Builder(
        builder: (context) => Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(text, maxLines: expand ? null : widget.maxLines, style: style),
            GestureDetector(
              onTap: () {
                expand = !expand;
                (context as Element).markNeedsBuild();
              },
              child: Text(
                expand ? '收起' : '展开',
                style: widget.markerStyle,
              ),
            ),
          ],
        ),
      );
    });
  }

  Widget buildAtText() {
    return LayoutBuilder(builder: (_, size) {
      final tp = TextPainter(
        text: TextSpan(text: '回复 @${widget.text}：', style: style),
        maxLines: maxLines,
        textDirection: TextDirection.ltr,
      );
      tp.layout(maxWidth: size.maxWidth);

      if (!tp.didExceedMaxLines)
        return Text.rich(
          TextSpan(
            children: [
              TextSpan(text: '回复 '),
              TextSpan(text: '@${widget.atName}', style: widget.markerStyle),
              TextSpan(text: '：${widget.text}'),
            ],
          ),
          style: style,
        );

      return Builder(
        builder: (context) => Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text.rich(
              TextSpan(
                children: [
                  TextSpan(text: '回复 '),
                  TextSpan(
                      text: '@${widget.atName}', style: widget.markerStyle),
                  TextSpan(text: '：${widget.text}'),
                ],
              ),
              maxLines: expand ? null : widget.maxLines,
              style: style,
            ),
            GestureDetector(
              onTap: () {
                expand = !expand;
                (context as Element).markNeedsBuild();
              },
              child: Text(
                expand ? '收起' : '展开',
                style: widget.markerStyle,
              ),
            ),
          ],
        ),
      );
    });
  }

  @override
  build(context) => widget.atName == '' ? buildOrdinaryText() : buildAtText();
}
